home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / fdimg / —‹Œêsrc.lzh / prnt.c < prev    next >
C/C++ Source or Header  |  1993-01-07  |  45KB  |  2,104 lines

  1. #include    "3DDEF.H"
  2. #include    "GLOBAL.H"
  3. #include    "FORWARD.H"
  4. #include    "XCODE.H"
  5.  
  6. int xpp[] = {2,12,26,38,48,58,68,73};
  7. int xpp_2[] = {20,35,46,57};
  8.  
  9. int prnt_top=0,prnt_last=0,prnt_pitch=0;
  10. int last_pn = -1;
  11.  
  12. void
  13. prnt_do()
  14. {
  15.     int ydot,ydot0,i,ii,lc,pn;
  16.     UNIT *wp,*wp0;
  17.     UBYTE ws[VERY_LONG_LINE],w0[VERY_LONG_LINE];
  18.     int xp;
  19.     int prnt_top0,prnt_last0;
  20.  
  21.     line_seigyou();
  22.     wp = HEAD->ATO;
  23.     lc = 0;
  24.     pn = 1;
  25.     while(wp != TAIL) {
  26.         lc++;
  27.         wp = wp->ATO;
  28.     }
  29.  
  30.     if (!PRN_JIZUME) {
  31.         PRN_JIZUME = CURRENT_JIZUME;
  32.     }
  33.     prnt_do_disp(xp = 7);
  34.  
  35.     while(1) {
  36.         UWORD c;
  37.  
  38.         fep_key_clear();
  39.         c = toupper(fep_inkey_raw0());
  40.         if ((c == 'M'-'@') || (c == CR) || (c == 'Y')) {
  41.             if ((PRN_JIZUME+4)*(12+(PRN_H_PITCH/2))+PRN_LEFT_MARGIN
  42.                  <= PRN_HDOT) {    /* 範囲内に納まっている */
  43.                              /* +4 は禁則分 */
  44.                 break;
  45.             } else {
  46.                 under_print0("横幅が制限を越えています。\\
  47. 設定し直して下さい[Push 'Y' Key]");
  48.                 while(1) {
  49.                     UBYTE c;
  50.  
  51.                     etc_beep();
  52.                     c = toupper(fep_inkey_raw0());
  53.                     if (c == 'Y') {
  54.                         break;
  55.                     }
  56.                 }
  57.                 prnt_do_disp(xp);
  58.                 continue;
  59.             }
  60.             break;
  61.         } else if (c == XF_LEFT_KOHO_KEY) {
  62.             if (xp) {
  63.                 xp--;
  64.             } else {
  65.                 xp = 7;
  66.             }
  67.             window_abs_loc(xpp[xp],UNDER_Y);
  68.         } else if (c == XF_RIGHT_KOHO_KEY) {
  69.             if (xp == 7) {
  70.                 xp = 0;
  71.             } else {
  72.                 xp++;
  73.             }
  74.             window_abs_loc(xpp[xp],UNDER_Y);
  75.         } else if ((c == '['-'@') || (c == 'G'-'@')) {
  76. /*            under_print((STR)"印刷を中止しました");*/
  77.             return;
  78.         } else if (('0' <=c) && (c <= '9')) {    /* 数字入力 */
  79.             prnt_direct_number(xp,c);
  80. /*            prnt_do_disp(xp);*/
  81.         } else if ((c == 'V') || (c == 'V'-'@')) {    /* pre view */
  82.             UBYTE ws[VERY_LONG_LINE];
  83.             UBYTE c0;
  84.  
  85. view_loop:
  86.             init_clear_screen();
  87.             sprintf(ws,"縮尺率を選んで下さい(1,2,4,8):中止 = [ESC]");
  88.             under_print_view(ws);
  89.             fep_key_clear();
  90.             c0 = toupper(fep_inkey_raw0());
  91.             switch(c0) {
  92.             case '1':
  93.             prnt_view(c,1,1);
  94.             break;
  95.  
  96.             case '2':
  97.             prnt_view(c,2,2);
  98.             break;
  99.  
  100.             case '4':
  101.             prnt_view(c,4,4);
  102.             break;
  103.  
  104.             case '8':
  105.             prnt_view(c,8,8);
  106.             break;
  107.  
  108.             case '\x1b':    /* ESC */
  109. /*            etc_func_on();*/
  110. /*            under_blanc();*/
  111.             ctrl_l();
  112.             break;
  113.  
  114.             default:
  115.             etc_beep();
  116.             goto view_loop;
  117.             }
  118.             return;
  119. /*            break;*/
  120.         } else {
  121.             int delta = 0;
  122.  
  123.             if (c == XF_NEXT_BLOCK_KEY) {
  124.                 delta = -1;
  125.             } else if (c == XF_BEFORE_BLOCK_KEY) {
  126.                 delta = 1;
  127.             } else {
  128. /*                etc_beep();*/
  129. /*                continue;*/
  130.             }
  131.  
  132.             if (fep_shift_ctrl() == 0x20) {    /* CTRL だ */
  133.                 delta *= 10;
  134.             }
  135.  
  136.             switch(xp) {
  137.             case 0:
  138.             if (delta) {
  139.                 PRN_TATE_MODE = !PRN_TATE_MODE;
  140.             }
  141.             break;
  142.  
  143.             case 1:
  144.             PRN_JIZUME = prnt_parm(PRN_JIZUME,delta);
  145.             break;
  146.  
  147.             case 2:
  148.             PAGE = prnt_parm(PAGE,delta);
  149.             break;
  150.  
  151.             case 3:
  152.             PRN_UP_MARGIN = prnt_parm(PRN_UP_MARGIN,delta);
  153.             break;
  154.  
  155.             case 4:
  156.             PRN_LEFT_MARGIN = prnt_parm(PRN_LEFT_MARGIN,delta);
  157.             break;
  158.  
  159.             case 5:
  160.             PRN_H_PITCH = prnt_parm(PRN_H_PITCH,delta);
  161.             break;
  162.  
  163.             case 6:
  164.             PRN_V_PITCH = min(prnt_parm(PRN_V_PITCH,delta),50);
  165.             break;
  166.  
  167.             default:
  168.             break;
  169.             }
  170.             prnt_do_disp(xp);
  171.         }
  172.     }
  173.  
  174. /* 印刷開始 */
  175.     prnt_do_disp_2(xp = 3);
  176.     while(1) {
  177.         UWORD c;
  178.  
  179.         fep_key_clear();
  180.             c = toupper(fep_inkey_raw0());
  181.         if ((c == 'M'-'@') || (c == CR) || (c == 'Y')) {
  182.             break;        /* 印刷開始 */
  183.         } else if (c == XF_LEFT_KOHO_KEY) {
  184.             if (xp) {
  185.                 xp--;
  186.             } else {
  187.                 xp = 3;
  188.             }
  189.             window_abs_loc(xpp_2[xp],UNDER_Y);
  190.         } else if (c == XF_RIGHT_KOHO_KEY) {
  191.             if (xp == 3) {
  192.                 xp = 0;
  193.             } else {
  194.                 xp++;
  195.             }
  196.             window_abs_loc(xpp_2[xp],UNDER_Y);
  197.         } else if ((c == '['-'@') || (c == 'G'-'@')) {
  198. /*            under_print((STR)"印刷を中止しました");*/
  199.             return;
  200.         } else if (('0' <=c) && (c <= '9')) {    /* 数字入力 */
  201.             prnt_direct_number2(xp,c);
  202. /*            prnt_do_disp(xp);*/
  203.         } else {
  204.             int delta = 0;
  205.  
  206.             if (c == XF_NEXT_BLOCK_KEY) {
  207.                 delta = -1;
  208.             } else if (c == XF_BEFORE_BLOCK_KEY) {
  209.                 delta = 1;
  210.             } else {
  211.                 continue;
  212.             }
  213.  
  214.             if (fep_shift_ctrl() == 0x20) {    /* CTRL だ */
  215.                 delta *= 10;
  216.             }
  217.             switch(xp) {
  218.             case 0:
  219.             prnt_top = prnt_parm(prnt_top,delta);
  220.             break;
  221.  
  222.             case 1:
  223.             prnt_last = prnt_parm(prnt_last,delta);
  224.             break;
  225.  
  226.             case 2:
  227.             prnt_pitch = !prnt_pitch;
  228.             break;
  229.  
  230.             default:
  231.             continue;
  232.             break;
  233.             }
  234.             prnt_do_disp_2(xp);
  235.         }
  236.     }
  237.  
  238.     under_print0("印刷中…");
  239.     if (prnt_out_string(PRN_INIT)) {
  240.         return;
  241.     }
  242.  
  243.     if (prnt_top0 = prnt_top) {
  244.     } else {
  245.         prnt_top0 = 1;
  246.     }
  247.     if (prnt_last0 = prnt_last) {
  248.     } else {
  249.         prnt_last0 = 99999;
  250.     }
  251.  
  252.  
  253.     if (prnt_top0 <= pn) {
  254.         ydot = prnt_do_up_margin();
  255.     } else {
  256.         ydot = 0;
  257.     }
  258.  
  259.     wp = HEAD->ATO;
  260.     ii = i = 0;
  261.     *w0 = EOS;
  262.     while((wp != TAIL) || (*w0)) {
  263.         if (!PAGE || (i++ < PAGE)) {    /* 1頁行数 */
  264.             if (PRN_JIZUME == CURRENT_JIZUME) {
  265.                 line_get_body(ws,wp);
  266.                 wp = wp->ATO;
  267.                 ii++;
  268.                 if (prnt_check(prnt_top0,pn,prnt_last0,prnt_pitch)) {
  269.                     if (PAGE) {
  270.                         prnt_repo_ln(ii,lc,pn,i);
  271.                     } else {
  272.                         prnt_repo_ln(ii,lc,pn,ii);
  273.                     }
  274.                 }
  275.             } else {
  276.                 if (!*w0) {    /* w0 が空ならば */
  277.                     line_get_body(w0,wp);
  278.                     wp = wp->ATO;
  279.                     ii++;
  280.                     if (prnt_check(prnt_top0,pn,prnt_last0,prnt_pitch)) {
  281.                         prnt_repo_ln(ii,lc,pn,i);
  282.                     }
  283.                 }
  284.                 cut_line(w0,ws,w0,PRN_JIZUME);
  285.                 if (!*w0) {    /* 1行取れなかった */
  286.                     while(1) {
  287.                         if (wp == TAIL) {
  288.                             *w0 = EOS;
  289.                             break;
  290.                         }
  291.                         /* 後がある */
  292.                         strcpy(w0,ws);    /* 戻す */
  293.                         line_cat_body(w0,wp);    /* 追加する */
  294.                         wp = wp->ATO;
  295.                         ii++;
  296.                         if (prnt_check(prnt_top0,pn,prnt_last0,prnt_pitch)) {
  297.                             prnt_repo_ln(ii,lc,pn,i);
  298.                         }
  299.                         cut_line(w0,ws,w0,PRN_JIZUME);
  300.                         if (*w0) {    /* 1行取れた */
  301.                              break;
  302.                         }
  303.                     }
  304.                 }
  305.             }
  306.             if (prnt_check(prnt_top0,pn,prnt_last0,prnt_pitch)) {
  307.                 ydot += prnt_bit_convrt_24(ws,ydot,LYW_UPPER,LYW_MAIN,LYW_UNDER,PRN_JIZUME);
  308.                 /* 変換する */
  309.             }
  310.         }
  311. saba:
  312.         if (fep_INKEY()) {
  313.             if (prnt_check_quit()) {
  314.                 return;
  315.             }
  316.         }
  317.         if (ydot >= HDOT) {    /* 1行をビットイメージ印字できる */
  318.             ydot0 = 0;
  319.             while((ydot - ydot0) >= HDOT) {
  320.                 if (prnt_send_1line_to_prn(ydot0,HDOT)) {
  321.                     return;
  322.                 }
  323.                 prnt_out_string(PRN_CRLF);
  324.                 ydot0 += HDOT;
  325.             }
  326.             prnt_shift_prnt_buff(ydot0,ydot);
  327.             ydot -= ydot0;
  328.             goto saba;
  329.         } else {
  330.             if ((PAGE && (i >= PAGE)) || (wp == TAIL)) {
  331.                 if (ydot) {    /* 1ヘッドに満たない残りがある */
  332.                     prnt_erase_box(ydot,HDOT);
  333.                     if (prnt_send_1line_to_prn(0,HDOT)) {
  334.                         return;
  335.                     }
  336.                     prnt_out_string(PRN_CRLF);
  337.                     ydot = 0;
  338.                 }
  339.                 if (wp == TAIL) {
  340.                     break;
  341.                 } else {    /* PAGE END */
  342.                     if (prnt_check(prnt_top0,pn,prnt_last0,prnt_pitch)) {
  343.                         if (prnt_ff()) {
  344.                             return;
  345.                         }
  346.                     }
  347.                     i = 0;
  348.                     pn++;
  349.                     if ((prnt_last) && (prnt_last < pn)) {
  350.                         break;    /* 最終指定を越えた */
  351.                     }
  352.                     if (prnt_check(prnt_top0,pn,prnt_last0,prnt_pitch)) {
  353.                         ydot = prnt_do_up_margin();
  354.                     }
  355.                 }
  356.             }
  357.         }
  358.     }
  359.     prnt_out_string(PRN_RESET);
  360.     under_blanc();
  361. }
  362.  
  363. /* ページ番号をチェック */
  364. int
  365. prnt_check(int prnt_top0,int pn,int prnt_last0,int prnt_pitch)
  366. {
  367.     if ((pn < prnt_top0) || (pn > prnt_last0)) {
  368.         return(0);    /* 範囲から出ている */
  369.     }
  370.     if (prnt_pitch && ((pn - prnt_top0) & 1)) {    /* 1頁おき指定で、差が奇数 */
  371.         return(0);
  372.     }
  373.     return(1);
  374. }
  375.  
  376. void
  377. prnt_do_disp(int xp)
  378. {
  379.     UBYTE ws[VERY_LONG_LINE];
  380.  
  381. /*            0          1        2      3        4          5        6      7        8
  382.                     01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678*/
  383.     sprintf(ws,
  384. "[%s]印刷,[%3d]字詰め,頁[%3d]行,上幅[%3d],左幅[%3d],横間[%3d],行間[%3d],<NL,←,→,↑,↓,View,ESC>",
  385.  
  386.     PRN_TATE_MODE?"縦":"横",PRN_JIZUME,
  387.     PAGE,PRN_UP_MARGIN,PRN_LEFT_MARGIN,PRN_H_PITCH,PRN_V_PITCH);
  388.     under_print00(ws);
  389.     window_abs_loc(xpp[xp],UNDER_Y);
  390. }
  391.  
  392. void
  393. prnt_do_disp_2(int xp)
  394. {
  395.     UBYTE ws[VERY_LONG_LINE],w0[VERY_LONG_LINE];
  396.     int delta;
  397.  
  398. /*            0          1        2      3        4          5        6      7        8
  399.                     01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678*/
  400.     delta = 0;
  401.     strcpy(ws,"\x1b[0K印刷パラメータ:");
  402.     if (prnt_top) {
  403.         delta = 2;
  404.         sprintf(w0,"第[%4d]頁から,",prnt_top);
  405.         strcat(ws,w0);
  406.     } else {
  407.         strcat(ws,"    先頭頁から,");
  408.     }
  409.     if (prnt_last) {
  410.         delta = 2;
  411.         sprintf(w0,"第[%4d]頁まで,",prnt_last);
  412.         strcat(ws,w0);
  413.     } else {
  414.         strcat(ws,"    最終頁まで,");
  415.     }
  416.     if (prnt_pitch) {
  417.         sprintf(w0,"1頁おき",prnt_last);
  418.         strcat(ws,w0);
  419.     } else {
  420.         strcat(ws,"連続    ");
  421.     }
  422.     strcat(ws,",<NL,←,→,↑,↓,ESC>");
  423.  
  424.     under_print00(ws);
  425.     window_abs_loc(xpp_2[xp]+delta,UNDER_Y);
  426. }
  427.  
  428. void
  429. prnt_repo_ln(int ln,int tl,int pn,int i)
  430. {
  431.     UBYTE w[MAXLINE];
  432.  
  433.     sprintf(w," 画面上の全 %d 行中の、第 %d 行目を処理中\\
  434. (第 %d 頁目の %d 行目を印刷中)・・・",tl,ln,pn,i);
  435.     under_print0(w);
  436. }
  437.  
  438. WORD
  439. prnt_parm(WORD parm,int delta)
  440. {
  441.     return((parm + delta + 1000) % 1000);
  442. }
  443.  
  444. int
  445. prnt_bit_convrt_24(STR dd,int ybgn,int u,int m,int l,int jj)
  446. {
  447.     register int i,x,xb,y;
  448.     register UINT c;
  449.     FNTDATA BUF;
  450.     int yhaba,yhaba0,xhaba,xhaba0;
  451.     int dx,ccount;
  452.     UBYTE *dp;
  453.     UBYTE ul_flag[PRN_MAX_CHAR];
  454.     register int ybgn_u,ybgn_u_m2;
  455.  
  456.     u += (u>>1);    /* 1.5 倍 */
  457.     m += (m>>1);    /* 1.5 倍 */
  458.     l += (l>>1);    /* 1.5 倍 */
  459.  
  460.     ybgn_u_m2 = (ybgn_u = ybgn+u) + m + 2;
  461.  
  462.      yhaba = u+m+l+PRN_V_PITCH;
  463.  
  464.     prnt_erase_box(ybgn,ybgn+yhaba);
  465.  
  466.     for(i=0;i<PRN_MAX_CHAR;i++) {    /* 下線フラグ消去 */
  467.         ul_flag[i] = 0;
  468.     }
  469. /* ,,, */
  470.     dx = PRN_LEFT_MARGIN;
  471.     ccount = i = 0;
  472.     while(c = dd[i++]) {
  473.         x = dx/8;    /* 水平バイト */
  474.         xb = dx%8;    /* 水平ビット */
  475.  
  476.         if (c == XCODE_UP) {    /* XCODE である */
  477.             switch(dd[i++]) {
  478.             register int oldx,newx,worki,worki0;
  479.             register int olddx,newdx;
  480.  
  481.             case XCODE_UL:    /* 下線だ */
  482.             if (l) {
  483.                 c = *line_skip_xcode(&dd[i]);
  484.                 if (c == TAB) {
  485.                     /* 0-7 -> 8, 8-15 -> 16... である */
  486.                     newx = oldx = ccount;
  487.                     newx += TAB_LENGTH;
  488.                     newx -= (newx % TAB_LENGTH);
  489.                     for(worki=oldx;worki<newx;worki++) {
  490.                         ul_flag[worki] = 1;
  491.                     }
  492.                 } else if (etc_char_disp_len(c) == 1) {    /* 半角幅 */
  493.                     oldx = ccount;
  494.                     newx = ccount+1;
  495.                     ul_flag[ccount] = 1;
  496.                 } else {        /* 全角だ */
  497.                     oldx = ccount;
  498.                     newx = ccount+2;
  499.                     ul_flag[ccount] = ul_flag[ccount+1] = 1;
  500.                 }
  501.                 newdx = (12+PRN_H_PITCH/2)*newx;
  502.                 if (oldx && ul_flag[oldx-1]) {    /* 左も下線 */
  503.                     olddx = dx-(12+PRN_H_PITCH/2);
  504.                 } else {
  505.                     olddx = dx;
  506.                 }
  507.                 /* olddx から newdx へ下線を引く */
  508.                 worki = olddx/8;
  509.                 worki0 = newdx/8;
  510.                 {
  511.                     UBYTE hanpa[8] = {0,1,3,7,15,31,63,127};
  512.  
  513.                     if (olddx % 8) {    /* 半端がある */
  514.                         *((UBYTE *)(&PRN_PAT[ybgn_u_m2][worki++]))
  515.                         |= hanpa[olddx % 8];
  516.                     }
  517.                     while(worki<worki0) {
  518.                         *((UBYTE *)(&PRN_PAT[ybgn_u_m2][worki++])) |= 0xff;
  519.                     }
  520.                     if (newdx % 8) {    /* 半端がある */
  521.                         *((UBYTE *)(&PRN_PAT[ybgn_u_m2][worki]))
  522.                         |= 255-hanpa[8-(newdx % 8)];
  523.                     }
  524.                 }
  525.             }
  526.             break;
  527.  
  528.             case XCODE_RB10:
  529.             c = (dd[i]<<8) | dd[i+1];
  530.             i += 2;
  531.             if (u) {
  532.                 prnt_rubi_put(dx+6,ybgn,c);
  533.             }
  534.             break;
  535.  
  536.             case XCODE_RB1:
  537.             case XCODE_RB1L:
  538.             c = (dd[i]<<8) | dd[i+1];
  539.             i += 2;
  540.             if (u) {
  541.                 prnt_rubi_put(dx,ybgn,c);
  542.             }
  543.             break;
  544.  
  545.             case XCODE_RB1R:
  546.             c = (dd[i]<<8) | dd[i+1];
  547.             i += 2;
  548.             if (u) {
  549.                 prnt_rubi_put(dx+12,ybgn,c);
  550.             }
  551.             break;
  552.  
  553.             case XCODE_RB2:
  554.             c = (dd[i]<<8) | dd[i+1];
  555.             if (u) {
  556.                 prnt_rubi_put(dx,ybgn,c);
  557.             }
  558.             c = (dd[i+2]<<8) | dd[i+3];
  559.             i += 4;
  560.             if (u) {
  561.                 prnt_rubi_put(dx+12,ybgn,c);
  562.             }
  563.             break;
  564.             }
  565.             continue;
  566.         }
  567.  
  568.         if ((c >= 0x80) && (!iskana(c))) {
  569.             c = (c<<8) | dd[i++];
  570.         } else if (c == CR) {    /* 改行である */
  571.             continue;
  572.         } else if (c == TAB) {    /* タブである */
  573.             int oldx;
  574.  
  575.             /* 0-7 -> 8, 8-15 -> 16... である */
  576.             oldx = ccount;
  577.             ccount += TAB_LENGTH;
  578.             ccount -= (ccount % TAB_LENGTH);
  579.             dx += (12+PRN_H_PITCH/2)*(ccount - oldx);
  580.             continue;
  581.         }
  582.         FNTGET(12,c,&BUF);
  583.         if (PRN_TATE_MODE) {
  584.             etc_rot_font(c,&BUF);
  585.         }
  586.         xhaba0 = BUF.xl;
  587.         yhaba0 = BUF.yl;
  588.         dp = BUF.buffer;
  589.         for(y=0;y<yhaba0;y++) {
  590.             register UINT p0;
  591.             register UBYTE *pb;
  592.             if (xhaba0 == 12) {    /* 半角だ */
  593.                 if (p0 = (dp[0]<<16)|(dp[1]<<8)) {
  594.                     if (x & 1) {    /* 奇数 */
  595.                         *((int *)(pb = &PRN_PAT[ybgn_u+y][x-1])) |= (p0 >> xb);
  596.                         if (xb) {
  597.                             pb[4] |= (p0 << (8-xb));
  598.                         }
  599.                     } else {    /* 偶数 */
  600.                         *((int *)(&PRN_PAT[ybgn_u+y][x])) |= (p0 << (8-xb));
  601.                     }
  602.                 }
  603.                 dp += 2;
  604.                 /*printf("[%12b]\n",p0);*/
  605.             } else {        /* 全角だ */
  606.                 if ((int)dp & 1) {    /* 奇数 */
  607.                     p0 = *((int *)(dp -1));
  608.                 } else {    /* 偶数 */
  609.                     p0 = *((int *)(dp)) >> 8;
  610.                 }
  611. /*                p0 = (dp[0]<<16)|(dp[1]<<8)|(dp[2])) {*/
  612. /*                if (p0 = (dp[0]<<16)|(dp[1]<<8)|(dp[2])) {*/
  613.                 if (p0 &= 0xffffff) {
  614.                     if (x & 1) {    /* 奇数 */
  615.                         *((int *)(pb = &PRN_PAT[ybgn_u+y][x-1])) |= (p0 >> xb);
  616.                         if (xb) {
  617.                             pb[4] |= (p0 << (8-xb));
  618.                         }
  619.                     } else {    /* 偶数 */
  620.                         *((int *)(&PRN_PAT[ybgn_u+y][x])) |= (p0 << (8-xb));
  621.                     }
  622.                 }
  623.                 dp += 3;
  624.                 /*printf("[%24b]\n",p0);*/
  625.             }
  626.         }
  627.         if (xhaba0 == 12) {    /* 半角だ */
  628.             ccount++;
  629.             dx += (xhaba0+PRN_H_PITCH/2);
  630.         } else {
  631.             ccount += 2;
  632.             dx += (xhaba0+PRN_H_PITCH);
  633.         }
  634.     }
  635.     return(yhaba);
  636. }
  637.  
  638. void
  639. prnt_rubi_put(int dx,int ybgn,UWORD c)
  640. {
  641.     FNTDATA BUF;
  642.     int xhaba0,yhaba0;
  643.     register int i,x,xb,y;
  644.     UBYTE *dp;
  645.  
  646.     x = dx/8;    /* 水平バイト */
  647.     xb = dx%8;    /* 水平ビット */
  648.     FNTGET(12,c,&BUF);
  649.     xhaba0 = BUF.xl;
  650.     yhaba0 = BUF.yl;
  651.     dp = BUF.buffer;
  652.     for(y=0;y<yhaba0;y++) {
  653.         register int p0;
  654.  
  655.         p0 = (dp[0]<<16)|(dp[1]<<8);
  656.         if (x & 1) {    /* 奇数 */
  657.             *((int *)(&PRN_PAT[ybgn+y][x-1])) |= (p0 >> xb);
  658.             if (xb) {
  659.                 PRN_PAT[ybgn+y][x-1+4] |= (p0 << (8-xb));
  660.             }
  661.         } else {    /* 偶数 */
  662.             *((int *)(&PRN_PAT[ybgn+y][x])) |= (p0 << (8-xb));
  663.         }
  664.         dp += 2;
  665.     }
  666. }
  667.  
  668. /* bgnd から hd ドットまでをプリンタに送り出す */
  669. /* 中断されたかどうかを返す */
  670. int
  671. prnt_send_1line_to_prn(int bgnd,int hd)
  672. {
  673.     register int x,b,i,mask;
  674.     UBYTE w[HDOT];
  675.     UBYTE wd[HDOT][8];
  676.     int xjj,xjj8;
  677.  
  678.     xjj = min((PRN_JIZUME+6)*(12+(PRN_H_PITCH/2))+PRN_LEFT_MARGIN
  679.         ,PRN_PAT_H*8);    /* ドット数 */
  680.     xjj = (xjj/8) + !!(xjj & 7);    /* バイト数(仮) */
  681.  
  682.     /* xjj が0ということはない */
  683.     do {
  684.         x = xjj-1;
  685.         for(i=0;i<HDOT;i++) {
  686.             if (PRN_PAT[bgnd+i][x]) {    /* 縦24バイトチェック */
  687.                 goto prnt_found;
  688.             }
  689.         }
  690.     } while(--xjj > 0);
  691.  
  692. prnt_found:
  693.  
  694.     if (xjj8 = xjj*8) {
  695.         if (prnt_bit_in(xjj8)) {    /* BIT IN */
  696.             return(1);
  697.         }
  698.     }
  699.     for(x=0;x<xjj;x++) {
  700.         for(i=0;i<HDOT;i++) {
  701.             w[i] = PRN_PAT[bgnd+i][x];    /* 縦24バイト取る */
  702.         }
  703.         mask = 128;    /* wd[][] のマトリックスにコンバート */
  704.         for(b=0;b<8;b++) {
  705.             for(i=0;i<HDOT;i++) {
  706.                 wd[i][b] = !!(w[i] & mask);
  707.             }
  708.             mask >>= 1;
  709.         }
  710.         if (PRN_MSB_IS_UP) {
  711.             for(b=0;b<8;b++) {
  712.                 mask = 0;
  713.                 for(i=0;i<8;i++) {
  714.                     mask |= (wd[i][b] << (7-i));
  715.                 }
  716.                 if (prnt_outlpt(mask)) {
  717.                     return(1);
  718.                 }
  719.                 mask = 0;
  720.                 for(i=8;i<16;i++) {
  721.                     mask |= (wd[i][b] << (7-(i-8)));
  722.                 }
  723.                 if (prnt_outlpt(mask)) {
  724.                     return(1);
  725.                 }
  726.                 mask = 0;
  727.                 for(i=16;i<24;i++) {
  728.                     mask |= (wd[i][b] << (7-(i-16)));
  729.                 }
  730.                 if (prnt_outlpt(mask)) {
  731.                     return(1);
  732.                 }
  733.             }
  734.         } else {
  735.             for(b=0;b<8;b++) {
  736.                 mask = 0;
  737.                 for(i=0;i<8;i++) {
  738.                     mask |= (wd[i][b] << (i));
  739.                 }
  740.                 if (prnt_outlpt(mask)) {
  741.                     return(1);
  742.                 }
  743.                 mask = 0;
  744.                 for(i=8;i<16;i++) {
  745.                     mask |= (wd[i][b] << (i-8));
  746.                 }
  747.                 if (prnt_outlpt(mask)) {
  748.                     return(1);
  749.                 }
  750.                 mask = 0;
  751.                 for(i=16;i<24;i++) {
  752.                     mask |= (wd[i][b] << (i-16));
  753.                 }
  754.                 if (prnt_outlpt(mask)) {
  755.                     return(1);
  756.                 }
  757.             }
  758.         }
  759.     }
  760.     return(0);
  761. }
  762.  
  763. /* 中断が指定されたかどうかを返す */
  764. int
  765. prnt_out_string(STR s)
  766. {
  767.     while(*s) {
  768.         if (prnt_outlpt(*s++)) {
  769.             return(1);
  770.         }
  771.     }
  772.     return(0);
  773. }
  774.  
  775. /* イメージバッファを上にシフトする */
  776. void
  777. prnt_shift_prnt_buff(int bgnd,int last)
  778. {
  779.     register int i,x,c;
  780.  
  781.     for(c=0,i=bgnd;i<last;c++,i++) {
  782.         for(x=0;x<PRN_PAT_H;x++) {
  783.             PRN_PAT[c][x] = PRN_PAT[i][x];
  784.         }
  785.     }
  786. }
  787.  
  788. /* バイト数がパラメータ */
  789. int
  790. prnt_bit_in(int bn)
  791. {
  792.     int i,n;
  793.     UBYTE f,c;
  794.     UBYTE w[MAXLINE];
  795.     int bnh,bnl;
  796.  
  797.     for(i=0;c = PRN_GIN[i++];) {
  798.         if (prnt_outlpt(c)) {
  799.             return(1);
  800.         }
  801.     }
  802.  
  803. /* n <D,M,I> で入っている */
  804.     n = PRN_GIN[i++];
  805.     f = toupper(PRN_GIN[i]);
  806.     bnh = bn / 256;
  807.     bnl = bn % 256;
  808.  
  809.     switch(f) {
  810.     case 'D':    /* 10進数アスキーコード */
  811.     if ((0 < n) && (n <= 5)) {
  812.         sprintf(w,"%05d",bn);
  813.         for(i=5-n;i<5;i++) {
  814.             if (prnt_outlpt(w[i])) {
  815.                 return(1);
  816.             }
  817.         }
  818.     } else {
  819.         error("プリンタへのパラメータの指定が異常です");
  820.     }
  821.     break;
  822.  
  823.     case 'I':    /* インテル形式 */
  824.     i = bnh;
  825.     bnh = bnl;
  826.     bnl = i;    /* SWAP */
  827.  
  828.     case 'M':    /* モトローラ形式 */
  829.     if (prnt_outlpt(bnh)) {
  830.         return(1);
  831.     }
  832.     if (prnt_outlpt(bnl)) {
  833.         return(1);
  834.     }
  835.     break;
  836.  
  837.     default:
  838.         error("プリンタへのパラメータの指定が異常です");
  839.     }
  840. }
  841.  
  842. /*
  843. (TYPE=0)    :CZ-8PK8
  844. (PIN=24)    (MSBUP=1)
  845. (HDOT=2088)    (VDOT=1584)
  846. (HGAP=8)    (VGAP=8)
  847. (LEFT_MARGIN=0)    (UP_MARGIN=0)
  848. (CRLF=$0d$0a)    (FF=$0c)
  849. (GIN=$1b$4a%2m)    :2桁のモトローラ順
  850. (INIT=$1b$25$39$10):16/120 inchs
  851. (RESET=$1b$63$31):reset printer
  852. */
  853. /*
  854. (TYPE=1)    :BJ-10V(ESC/P:ただし24pin)
  855. (PIN=24)    (MSBUP=1)
  856. (HDOT=1272)    (VDOT=1920)
  857. (HGAP=8)    (VGAP=8)
  858. (LEFT_MARGIN=0)    (UP_MARGIN=0)
  859. (CRLF=$0d$0a)    (FF=$0c)
  860. (GIN=$1b$2a$27%2i)    :2桁のインテル順
  861. (INIT=$1b$41%08):16/120 inchs
  862. (RESET=$1b$40):reset printer
  863. */
  864. /*
  865. (TYPE=2)    :NM-????
  866. (PIN=24)    (MSBUP=0)
  867. (HDOT=1272)    (VDOT=1920)
  868. (HGAP=8)    (VGAP=8)
  869. (LEFT_MARGIN=0)    (UP_MARGIN=0)
  870. (CRLF=$0d$0a)    (FF=$0c)
  871. (GIN=$1b$4a%4d)    :4桁のアスキーコード
  872. (INIT=$1b$41%0c):16/120 inchs
  873. (RESET=$1b$63$31):reset printer
  874. */
  875. /*
  876. (TYPE=3)    :PC-????
  877. (PIN=24)    (MSBUP=0)
  878. (HDOT=1272)    (VDOT=1920)
  879. (HGAP=8)    (VGAP=8)
  880. (LEFT_MARGIN=0)    (UP_MARGIN=0)
  881. (CRLF=$0d$0a)    (FF=$0c)
  882. (GIN=$1b$4a%4d)    :4桁のアスキーコード
  883. (INIT=$1b$41%0c):16/120 inchs
  884. (RESET=$1b$63$31):reset printer
  885. */
  886. typedef struct PRN_DEFAULTS_UNIT {
  887.     UWORD pin;
  888.     UWORD msbup;
  889.     UWORD hdot;
  890.     UWORD vdot;
  891.     UWORD hgap;
  892.     UWORD vgap;
  893.     UWORD left_margin;
  894.     UWORD up_margin;
  895.  
  896.     UBYTE crlf[16];
  897.     UBYTE ff[16];
  898.     UBYTE gin[16];
  899.     UBYTE init[16];
  900.     UBYTE reset[16];
  901.     UBYTE name[32];
  902. } PRN_DEFAULTS_UNIT;
  903.  
  904. PRN_DEFAULTS_UNIT PRN_DEFAULTS[] = {
  905. {24,1,2448,1584,8,8,0,0,
  906. "$0d$0a","$0c","$1b$4a%2m","$1b$25$39$10","$1b$63$31","CZ-8PK8"},
  907. {24,1,1272,1920,8,8,0,0,
  908. "$0d$0a","$0c","$1b$2a$27%2i","$1b$41$08","$1b$40","BJ-10V(ESC/P)"},
  909. {24,0,2088,1584,8,8,0,0,
  910. "$0d$0a","$0c","$1b$4a%4d","$1b$54$31$36","$1b$63$31","NM-????"},
  911. {24,0,2088,1584,8,8,0,0,
  912. "$0d$0a","$0c","$1b$4a%4d","$1b$54$31$36","$1b$63$31","PC-????"}
  913. };
  914.  
  915. /* デフォルトの設定を行う */
  916. void
  917. prnt_set_type()
  918. {
  919.     PRN_PIN = PRN_DEFAULTS[PRN_TYPE].pin;
  920.     PRN_MSB_IS_UP = PRN_DEFAULTS[PRN_TYPE].msbup;
  921.     PRN_HDOT = PRN_DEFAULTS[PRN_TYPE].hdot;
  922.     PRN_VDOT = PRN_DEFAULTS[PRN_TYPE].vdot;
  923.     PRN_H_PITCH = PRN_DEFAULTS[PRN_TYPE].hgap;
  924.     PRN_V_PITCH = PRN_DEFAULTS[PRN_TYPE].vgap;
  925.     PRN_LEFT_MARGIN = PRN_DEFAULTS[PRN_TYPE].left_margin;
  926.     PRN_UP_MARGIN = PRN_DEFAULTS[PRN_TYPE].up_margin;
  927.  
  928.     init_by_cnf_prn_hex0(PRN_CRLF,PRN_DEFAULTS[PRN_TYPE].crlf);
  929.     init_by_cnf_prn_hex0(PRN_FF,PRN_DEFAULTS[PRN_TYPE].ff);
  930.     init_by_cnf_prn_hex_gin(PRN_GIN,PRN_DEFAULTS[PRN_TYPE].gin);
  931.     init_by_cnf_prn_hex0(PRN_INIT,PRN_DEFAULTS[PRN_TYPE].init);
  932.     init_by_cnf_prn_hex0(PRN_RESET,PRN_DEFAULTS[PRN_TYPE].reset);
  933. }
  934.  
  935. /* 中断が指定されたかどうかを返す */
  936. int
  937. prnt_outlpt(UBYTE c)
  938. {
  939.     register int t,t0;
  940.  
  941.     t0 = ONTIME();
  942.     while(SNSPRN() == 0) {
  943.         if ((t = ONTIME()) < t0) {    /* リセットされた */
  944.             t += 8640000;
  945.         }
  946.         if ((t - t0) > PRN_WAIT*100) {
  947.             while(1) {
  948.                 UWORD c;
  949.  
  950.                 etc_beep();
  951.                 under_print0((STR)"プリンタに出力できません。印刷を続行しますか [Y/N]? ");
  952.                 fep_key_clear();
  953.                 c = toupper(fep_inkey_raw0());
  954.                 if (c == 'N') {
  955. /*                    under_print((STR)"印刷を中止しました");*/
  956.                     return(1);
  957.                 } else if (c == 'Y') {
  958.                     break;
  959.                 }
  960.             }
  961.             t0 = t;
  962.         }
  963.     }
  964.     OUTLPT(c);
  965.     return(0);
  966. }
  967.  
  968. int
  969. prnt_check_quit()
  970. {
  971.     UINT c;
  972.  
  973.     while(1) {
  974.         under_print0((STR)"印刷を中止しますか [Y/N]? ");
  975.         fep_key_clear();
  976.         c = toupper(fep_inkey_raw0());
  977.         if (c == 'Y') {
  978. /*            under_print((STR)"印刷を中止しました");*/
  979.             prnt_out_string(PRN_RESET);
  980.             return(1);
  981.         } else if (c == 'N') {
  982.             break;
  983.         }
  984.     }
  985.     under_print((STR)"印刷を続行します");
  986.     return(0);
  987. }
  988.  
  989. int
  990. prnt_ff()
  991. {
  992.     return(prnt_out_string(PRN_FF));
  993. }
  994.  
  995. /* 新しいドット値を返す */
  996. int
  997. prnt_do_up_margin()
  998. {
  999.     register int i;
  1000.  
  1001.     for(i=PRN_UP_MARGIN/PRN_PIN;i;i--) {
  1002.         prnt_out_string(PRN_CRLF);
  1003.     }
  1004.     return(PRN_UP_MARGIN%PRN_PIN);
  1005. }
  1006.  
  1007. #if 0
  1008. void
  1009. prnt_erase_box(int y0,int y1)
  1010. {
  1011. #asm
  1012.     movem.l d3/d4,-(sp)
  1013.     move.l 12(sp),d0
  1014.     move.l 16(sp),d3
  1015. *    move.l d0,_sysflag
  1016. *    move.w d3,_UNDER_Y
  1017.     move.l d0,d2
  1018.     cmp.l d2,d3
  1019.     ble ?476__
  1020.     move.l #_PRN_PAT,d4
  1021.     move.l d0,d1
  1022.     add.l d0,d0
  1023.     add.l d1,d0
  1024.     asl.l #3,d0
  1025.     add.l d1,d0
  1026.     add.l d0,d0
  1027.     add.l d1,d0
  1028.     move.l d0,d1
  1029.     asl.l #3,d1
  1030. ?475__:
  1031.     move.l d1,d0
  1032.     move.l d4,a1
  1033.     add.l d0,a1
  1034.     move.w #407,a0
  1035. ?474__:
  1036.     clr.b (a0,a1.l)
  1037.     subq.w #1,a0
  1038.     cmp.w #-1,a0
  1039.     bne ?474__
  1040.     add.l #408,d1
  1041.     addq.l #1,d2
  1042.     cmp.l d2,d3
  1043.     bgt ?475__
  1044. ?476__:
  1045.     movem.l (sp)+,d3/d4
  1046.     rts
  1047. #endasm
  1048. }
  1049.  
  1050. void
  1051. prnt_erase_box(int y0,int y1)
  1052. {
  1053.     register int i,x;
  1054.  
  1055.     for(i=y0;i<y1;i++) {    /* 消去 */
  1056.         for(x=0;x<PRN_PAT_H;x++) {
  1057.             PRN_PAT[i][x] = 0;
  1058.         }
  1059.     }
  1060. }
  1061. #else
  1062.  
  1063. void
  1064. prnt_erase_box(int y0,int y1)
  1065. {
  1066. #asm
  1067.     move.l 4(sp),d0
  1068.     move.l d0,d1
  1069.     add.l d1,d1    *2
  1070.     add.l d0,d1    *3
  1071.     asl.l #3,d1    *24
  1072.     add.l d0,d1    *25
  1073.     add.l d1,d1    *50
  1074.     add.l d0,d1    *51
  1075.     asl.l #3,d1    *408
  1076.     move.l d1,a0
  1077.     add.l #_PRN_PAT,a0    *a0 = ptr
  1078.  
  1079.     move.l 8(sp),d1
  1080.     sub.l d0,d1    *y1-y0
  1081.     move.l d1,d0
  1082.     add.l d0,d0    *2
  1083.     add.l d1,d0    *3
  1084.     asl.l #3,d0    *24
  1085.     add.l d1,d0    *25
  1086.     add.l d0,d0    *50
  1087.     add.l d1,d0    *51
  1088.     move.l d0,d1
  1089.     add.l d1,d1    *102
  1090.     beq ?466__
  1091.  
  1092.     moveq.l #0,d2
  1093. ?465__:
  1094.     move.l d2,(a0)+
  1095.     dbra d1,?465__
  1096. ?466__:
  1097.     rts
  1098. #endasm
  1099. }
  1100. #endif
  1101.  
  1102. #define    MAX_V        16*30
  1103. #define    MAX_MEM_PAGE    100
  1104.  
  1105. extern PM_UNIT page_last;
  1106.  
  1107. UBYTE view1[] = {
  1108. 0x00, 0x10, 0x10, 0x10, 0x20, 0x30, 0x30, 0x30,
  1109. 0x20, 0x30, 0x30, 0x30, 0x20, 0x30, 0x30, 0x30,
  1110. 0x40, 0x50, 0x50, 0x50, 0x60, 0x70, 0x70, 0x70,
  1111. 0x60, 0x70, 0x70, 0x70, 0x60, 0x70, 0x70, 0x70,
  1112. 0x40, 0x50, 0x50, 0x50, 0x60, 0x70, 0x70, 0x70,
  1113. 0x60, 0x70, 0x70, 0x70, 0x60, 0x70, 0x70, 0x70,
  1114. 0x40, 0x50, 0x50, 0x50, 0x60, 0x70, 0x70, 0x70,
  1115. 0x60, 0x70, 0x70, 0x70, 0x60, 0x70, 0x70, 0x70,
  1116. 0x80, 0x90, 0x90, 0x90, 0xa0, 0xb0, 0xb0, 0xb0,
  1117. 0xa0, 0xb0, 0xb0, 0xb0, 0xa0, 0xb0, 0xb0, 0xb0,
  1118. 0xc0, 0xd0, 0xd0, 0xd0, 0xe0, 0xf0, 0xf0, 0xf0,
  1119. 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xf0, 0xf0, 0xf0,
  1120. 0xc0, 0xd0, 0xd0, 0xd0, 0xe0, 0xf0, 0xf0, 0xf0,
  1121. 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xf0, 0xf0, 0xf0,
  1122. 0xc0, 0xd0, 0xd0, 0xd0, 0xe0, 0xf0, 0xf0, 0xf0,
  1123. 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xf0, 0xf0, 0xf0,
  1124. 0x80, 0x90, 0x90, 0x90, 0xa0, 0xb0, 0xb0, 0xb0,
  1125. 0xa0, 0xb0, 0xb0, 0xb0, 0xa0, 0xb0, 0xb0, 0xb0,
  1126. 0xc0, 0xd0, 0xd0, 0xd0, 0xe0, 0xf0, 0xf0, 0xf0,
  1127. 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xf0, 0xf0, 0xf0,
  1128. 0xc0, 0xd0, 0xd0, 0xd0, 0xe0, 0xf0, 0xf0, 0xf0,
  1129. 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xf0, 0xf0, 0xf0,
  1130. 0xc0, 0xd0, 0xd0, 0xd0, 0xe0, 0xf0, 0xf0, 0xf0,
  1131. 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xf0, 0xf0, 0xf0,
  1132. 0x80, 0x90, 0x90, 0x90, 0xa0, 0xb0, 0xb0, 0xb0,
  1133. 0xa0, 0xb0, 0xb0, 0xb0, 0xa0, 0xb0, 0xb0, 0xb0,
  1134. 0xc0, 0xd0, 0xd0, 0xd0, 0xe0, 0xf0, 0xf0, 0xf0,
  1135. 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xf0, 0xf0, 0xf0,
  1136. 0xc0, 0xd0, 0xd0, 0xd0, 0xe0, 0xf0, 0xf0, 0xf0,
  1137. 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xf0, 0xf0, 0xf0,
  1138. 0xc0, 0xd0, 0xd0, 0xd0, 0xe0, 0xf0, 0xf0, 0xf0,
  1139. 0xe0, 0xf0, 0xf0, 0xf0, 0xe0, 0xf0, 0xf0, 0xf0
  1140. };
  1141.  
  1142. UBYTE view2[] = {
  1143. 0x00, 0x01, 0x01, 0x01, 0x02, 0x03, 0x03, 0x03,
  1144. 0x02, 0x03, 0x03, 0x03, 0x02, 0x03, 0x03, 0x03,
  1145. 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x07, 0x07,
  1146. 0x06, 0x07, 0x07, 0x07, 0x06, 0x07, 0x07, 0x07,
  1147. 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x07, 0x07,
  1148. 0x06, 0x07, 0x07, 0x07, 0x06, 0x07, 0x07, 0x07,
  1149. 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x07, 0x07,
  1150. 0x06, 0x07, 0x07, 0x07, 0x06, 0x07, 0x07, 0x07,
  1151. 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0b, 0x0b, 0x0b,
  1152. 0x0a, 0x0b, 0x0b, 0x0b, 0x0a, 0x0b, 0x0b, 0x0b,
  1153. 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, 0x0f,
  1154. 0x0e, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x0f,
  1155. 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, 0x0f,
  1156. 0x0e, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x0f,
  1157. 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, 0x0f,
  1158. 0x0e, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x0f,
  1159. 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0b, 0x0b, 0x0b,
  1160. 0x0a, 0x0b, 0x0b, 0x0b, 0x0a, 0x0b, 0x0b, 0x0b,
  1161. 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, 0x0f,
  1162. 0x0e, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x0f,
  1163. 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, 0x0f,
  1164. 0x0e, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x0f,
  1165. 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, 0x0f,
  1166. 0x0e, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x0f,
  1167. 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0b, 0x0b, 0x0b,
  1168. 0x0a, 0x0b, 0x0b, 0x0b, 0x0a, 0x0b, 0x0b, 0x0b,
  1169. 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, 0x0f,
  1170. 0x0e, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x0f,
  1171. 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, 0x0f,
  1172. 0x0e, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x0f,
  1173. 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, 0x0f,
  1174. 0x0e, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x0f
  1175. };
  1176.  
  1177. /* bgnd から hd ドットまでをプレビューする */
  1178. /* 画面上での垂直表示増加ドット分を返す */
  1179. /* xr,yr : 縮尺レート */
  1180. int
  1181. prnt_send_1line_to_prn_view(int yyy,int bgnd,int hd,int xr,int yr)
  1182. {
  1183.     register int x,i,xjj;
  1184.     register STR PAT4 = PAT+4;
  1185.     register int hd_bgnd = hd-bgnd;
  1186.     int xjj8;
  1187.  
  1188.     if (yyy < 0) {
  1189.         return(0);
  1190.     }
  1191.  
  1192.     xjj8 = min((PRN_JIZUME+6)*(12+(PRN_H_PITCH/2))+PRN_LEFT_MARGIN
  1193.         ,PRN_PAT_H*8);    /* ドット数 */
  1194.     xjj = (xjj8/8) + !!(xjj8 & 7);    /* バイト数(仮) */
  1195.     /* xjj が0ということはない */
  1196.  
  1197.     switch(xr) {
  1198.     register int wb,c;
  1199.     register int wbx,cx;
  1200.  
  1201.     case 1:        /* xr = yr = 1 */
  1202.     for(i=0;i<hd_bgnd;i++) {
  1203.         for(x=0;x<xjj;x++) {
  1204.             (PAT4)[i*xjj + x] = PRN_PAT[bgnd+i][x];
  1205.         }
  1206.     }
  1207.     break;
  1208.  
  1209.     case 2:        /* xr = yr = 2 */
  1210.     for(i=0;i<hd_bgnd;i += 2) {
  1211.         register int i2xjj2 = (i/2)*(xjj/2);
  1212.  
  1213.         for(x=0;x<xjj;x += 2) {
  1214.  
  1215.             (PAT4)[i2xjj2++] = wbx =
  1216.               view1[PRN_PAT[bgnd+i][x] | PRN_PAT[bgnd+i+1][x]]
  1217.             | view2[PRN_PAT[bgnd+i][x+1] | PRN_PAT[bgnd+i+1][x+1]];
  1218.         }
  1219.     }
  1220.     break;
  1221.  
  1222.     case 4:
  1223.     for(i=0;i<hd_bgnd;i += 4) {
  1224.         register int i4xjj4 = (i/4)*(xjj/4);
  1225.  
  1226.         for(x=0;x<xjj;x += 4) {
  1227.             for(wbx=cx=0;cx<4;cx++) {
  1228.  
  1229.                 wb = PRN_PAT[bgnd+i][x+cx] | PRN_PAT[bgnd+i+1][x+cx]
  1230.                      | PRN_PAT[bgnd+i+2][x+cx] | PRN_PAT[bgnd+i+3][x+cx];
  1231.  
  1232.                 if (wb & 0xf0) wbx |= 128 >> (cx*2);
  1233.                 if (wb & 0x0f) wbx |= 128 >> (cx*2+1);
  1234.             }
  1235.             (PAT4)[i4xjj4 + (x/4)] = wbx;
  1236.         }
  1237.     }
  1238.     break;
  1239.  
  1240.     case 8:
  1241.     for(i=0;i<hd_bgnd;i += yr) {
  1242.         register int i8xjj8 = (i/8)*(xjj/8);
  1243.  
  1244.         for(x=0;x<xjj;x += 8) {
  1245.             for(wbx=cx=0;cx<8;cx++) {
  1246.                 if (PRN_PAT[bgnd+i][x+cx] | PRN_PAT[bgnd+i+1][x+cx]
  1247.                      | PRN_PAT[bgnd+i+2][x+cx] | PRN_PAT[bgnd+i+3][x+cx]
  1248.                      | PRN_PAT[bgnd+i+4][x+cx] | PRN_PAT[bgnd+i+5][x+cx]
  1249.                      | PRN_PAT[bgnd+i+6][x+cx] | PRN_PAT[bgnd+i+7][x+cx]) {
  1250.                     wbx |= (128 >> cx);
  1251.                 }
  1252.             }
  1253.             (PAT4)[i8xjj8 + (x/8)] = wbx;
  1254.         }
  1255.     }
  1256.     break;
  1257.  
  1258.     default:
  1259.     error("???1");
  1260.     }
  1261.  
  1262.     *((UWORD *) PAT0) = *((UWORD *) PAT) = (xjj*8) / xr;
  1263.     ((UWORD *) PAT0)[1] = ((UWORD *) PAT)[1] = hd / yr;
  1264.  
  1265.     disp_cursor_off();
  1266. /*window0();printf("[%d]",hd);binkey();*/
  1267.     etc_put_pattern(0,yyy,PAT,NULL);
  1268.     return(hd/yr);
  1269. }
  1270.  
  1271. /* 第1頁の先頭を格納する */
  1272. /* 格納したインデックスを返す */
  1273. int
  1274. prnt_vp_store(PM_UNIT page_mem[],UNIT *wp,int bp,int pn)
  1275. {
  1276.     register int i,w;
  1277.  
  1278.     for(i=0;i<MAX_MEM_PAGE;i++) {
  1279.         if ((w = page_mem[i].PN) == pn) {    /* 既にある */
  1280.             return(i);            /* 何もせずに帰る */
  1281.         }
  1282.         if (w == -1) {    /* フリーだ */
  1283.             page_mem[i].LP = wp;
  1284.             page_mem[i].BP = bp;
  1285.             page_mem[i].PN = pn;
  1286.             return(i);
  1287.         }
  1288.     }
  1289.     /* フリーが無い */
  1290.     for(i=0;i<MAX_MEM_PAGE;i++) {
  1291.         if (page_mem[i].PN != 1) {    /* 先頭頁ではない */
  1292.             page_mem[i].LP = wp;    /* 行をコロス */
  1293.             page_mem[i].BP = bp;
  1294.             page_mem[i].PN = pn;
  1295.             return(i);
  1296.         }
  1297.     }
  1298.     error("???2");
  1299. }
  1300.  
  1301. /* n 未満の最大を与えるインデックスを返す */
  1302. int
  1303. prnt_vp_maxi(PM_UNIT page_mem[],int n)
  1304. {
  1305.     register int i,w,max,maxi;
  1306.  
  1307.     max = page_mem[maxi = 0].PN;    /* 最初が初期値 */
  1308.     for(i=0;i < MAX_MEM_PAGE;i++) {
  1309.         if (((w = page_mem[i].PN) < n) && (w > 0) && (max > w)) {
  1310.             max = w;
  1311.             maxi = i;
  1312.         }
  1313.     }
  1314.     return(maxi);
  1315. }
  1316.  
  1317. /* page_last を作る */
  1318. void
  1319. prnt_vp_make_last(PM_UNIT page_mem[])
  1320. {
  1321.     int i;
  1322.  
  1323.     i = prnt_vp_get(page_mem,0xffff);    /* とにかく最大値 */
  1324.     page_last.LP = page_mem[i].LP;
  1325.     page_last.BP = page_mem[i].BP;
  1326.     page_last.PN = page_mem[i].PN;
  1327. }
  1328.  
  1329. /* wp0 の bp0 から1ページトレースする */
  1330. /* 次の wp0 と、bp0 を返す */
  1331. /* page_last なら NULL を返す */
  1332. UNIT *
  1333. prnt_vp_trace_page(UNIT *wp0,int *bp0)
  1334. {
  1335.     register UNIT *wp;
  1336.     UBYTE ws[VERY_LONG_LINE],w0[VERY_LONG_LINE];
  1337.     int i;
  1338.  
  1339.     if (!PAGE) {
  1340.         *bp0 = 0;
  1341.         return(NULL);    /* last page である */
  1342.     }
  1343.  
  1344.     wp = wp0;
  1345.      i = 0;
  1346.     if (*bp0) {    /* 最初が行の途中からである */
  1347.         line_get_body(ws,wp);
  1348.         strcpy(w0,&ws[*bp0]);
  1349.         wp = wp->ATO;
  1350.     } else {
  1351.         *w0 = EOS;
  1352.     }
  1353.  
  1354.     while((wp != TAIL) || (*w0)) {    /* まだ何か残っている */
  1355.         if (i++ < PAGE) {    /* まだ頁内に留まっている */
  1356.             if (PRN_JIZUME == CURRENT_JIZUME) {
  1357.                 line_get_body(ws,wp);
  1358.                 wp = wp->ATO;
  1359.             } else {
  1360.                 if (!*w0) {    /* w0 が空ならば */
  1361.                     line_get_body(w0,wp);
  1362.                     wp = wp->ATO;
  1363.                 }
  1364.                 cut_line(w0,ws,w0,PRN_JIZUME);
  1365.                 if (!*w0) {    /* 1行取れなかった */
  1366.                     while(1) {
  1367.                         if (wp == TAIL) {
  1368.                             *w0 = EOS;
  1369.                             break;
  1370.                         }
  1371.                         /* 後がある */
  1372.                         strcpy(w0,ws);    /* 戻す */
  1373.                         line_cat_body(w0,wp);    /* 追加する */
  1374.                         wp = wp->ATO;
  1375.                         cut_line(w0,ws,w0,PRN_JIZUME);
  1376.                         if (*w0) {    /* 1行取れた */
  1377.                              break;
  1378.                         }
  1379.                     }
  1380.                 }
  1381.             }
  1382.         } else {    /* 1頁終了 */
  1383.             if (!*w0) {    /* 残りが無い */
  1384.                 *bp0 = 0;
  1385.                 return(wp);
  1386.             } else {    /* 残りがある */
  1387.                 UBYTE ws[VERY_LONG_LINE];
  1388.  
  1389.                 line_get_body(ws,wp->MAE);
  1390.                 *bp0 = strlen(ws) - strlen(w0);
  1391.                 return(wp->MAE);
  1392.             }
  1393.         }
  1394.     }
  1395.  
  1396. /* TAIL に達した */
  1397.     return(NULL);
  1398. }
  1399.  
  1400. void
  1401. prnt_vp_init(PM_UNIT page_mem[])
  1402. {
  1403.     register int pmc;
  1404.  
  1405.     for(pmc = 0;pmc < MAX_MEM_PAGE;pmc++) {
  1406.         page_mem[pmc].PN = -1;    /* ページインデックスの初期化 */
  1407.     }
  1408.     page_last.PN = -1;
  1409. }
  1410.  
  1411. /*******************************/
  1412.  
  1413. #define    MAX_V        16*30
  1414. #define    MAX_MEM_PAGE    100
  1415. #define    MAX_MEM_LINE    100
  1416.  
  1417. PM_UNIT page_last;
  1418.  
  1419. /* pre view */
  1420. /* 縦横の圧縮率を与える */
  1421. void
  1422. prnt_view(UBYTE mode,int xr,int yr)
  1423. {
  1424.     UNIT *wp;
  1425.     int pn,bp;
  1426.     PM_UNIT page_mem[MAX_MEM_PAGE];
  1427.  
  1428.     prnt_vp_init(page_mem);    /* ページインデックスの初期化 */
  1429.     wp = HEAD->ATO;
  1430.     bp = 0;
  1431.     pn = 1;
  1432.     last_pn = -1;
  1433.  
  1434.     while(1) {
  1435.         prnt_vp_store(page_mem,wp,bp,pn);    /* 登録 */
  1436.         pn = prnt_do_1page_view(mode,wp,bp,page_mem,pn,xr,yr);
  1437.         if (pn < 0) {
  1438.             break;
  1439.         } else {
  1440.             int pmc;
  1441.  
  1442.             pmc = prnt_vp_get(page_mem,pn);
  1443.             wp = page_mem[pmc].LP;
  1444.             pn = page_mem[pmc].PN;
  1445.             bp = page_mem[pmc].BP;
  1446.         }
  1447.     }
  1448. }
  1449.  
  1450. /* 次に処理すべきページ番号を返す */
  1451. /* 終了ならば -1 を返す */
  1452. int
  1453. prnt_do_1page_view(UBYTE mode,UNIT *wp,int bp,PM_UNIT page_mem[],int pn,int xr,int yr)
  1454. {
  1455.     UBYTE work[MAXLINE];
  1456.     UINT c;
  1457.     int i,flag;
  1458.  
  1459.     init_clear_screen();
  1460.     while(1) {
  1461.         if (mode == 'V'-'@') {    /* 連続モード */
  1462.             flag = fep_INKEY();
  1463.             if ((flag == 'G'-'@') || (flag == '['-'@')) {
  1464.                 return(-1);
  1465.             }
  1466. /*window0();printf("(%d),(%d)",last_pn,pn);binkey();*/
  1467.             if (pn == last_pn) {
  1468.                 return(-1);
  1469.             }
  1470.             last_pn = pn;
  1471.         }
  1472.  
  1473.         flag = prnt_do_1page_view_sub(mode,&wp,&bp,pn,page_mem,xr,yr);
  1474. pager_key:
  1475.         prnt_repo_view(pn,wp);
  1476.         if (mode == 'V') {
  1477.             if (!flag) {
  1478.                 disp_cursor_on();
  1479.                 fep_key_clear();
  1480.                 c = fep_inkey_raw0();
  1481.                 disp_cursor_off();
  1482.             } else {
  1483.                 c = flag;
  1484.             }
  1485. /*
  1486. etc_beep();etc_beep();etc_beep();
  1487. window0();printf("[%x]",c);binkey();
  1488. */
  1489.             switch(c) {
  1490.             case 'G'-'@':
  1491. /*            case 'C'-'@':*/
  1492.             case '['-'@':
  1493.             return(-1);    /* 終了 */
  1494.  
  1495.             case 0x201:    /* [F1] *//* 最初の頁へ */
  1496.             return(1);
  1497.  
  1498.             case 0x202:    /* [F2] *//* 最後の頁へ */
  1499.             if (page_last.PN == -1) {    /* まだみてない */
  1500.                     /* ドロナワで作る */
  1501.                 prnt_vp_make_last(page_mem);
  1502.             }
  1503.             return(page_last.PN);
  1504.  
  1505.             case '0':
  1506.             case '1':
  1507.             case '2':
  1508.             case '3':
  1509.             case '4':
  1510.             case '5':
  1511.             case '6':
  1512.             case '7':
  1513.             case '8':
  1514.             case '9':    /* 10進数である */
  1515.             i = 0;    /* 始め */
  1516.             work[i++] = c;
  1517.             work[i] = EOS;
  1518. /*error("1");*/
  1519.             prnt_repo_view_num(work);    /* エコーバック */
  1520. /*error("2");*/
  1521.             while(1) {
  1522.                     if (isdigit(c = fep_inkey_raw0())) {
  1523.                     if (i < 8) {
  1524.                         work[i++] = c;
  1525.                         work[i] = EOS;
  1526.                     } else {
  1527.                         fep_key_clear();
  1528.                         etc_beep();
  1529.                     }
  1530.                 } else if (c == 'H'-'@') {    /* BS */
  1531.                     if (i) {
  1532.                         work[--i] = EOS;
  1533.                     }
  1534.                 } else if (c == '\x1b') {
  1535.                     work[0] = EOS;
  1536.                     break;
  1537.                 } else {
  1538.                     break;
  1539.                 }
  1540.                 prnt_repo_view_num(work);    /* エコーバック */
  1541.             }
  1542.             if ((c == CR) || (c == 'M'-'@')) {    /* CR で終了 */
  1543.                 if ((i = atoi(work)) > 0) {
  1544.                     return(i);
  1545.                 }
  1546.             }
  1547.                 /* 変なキー入力で終了 */
  1548.             etc_beep();
  1549.             goto pager_key;
  1550.  
  1551.             default:
  1552.             if (c == XF_BEFORE_PAGE_KEY) {    /* ROLL DN */
  1553.                 if (pn > 1) {
  1554.                     return(page_mem[prnt_vp_get(page_mem,pn-1)].PN);
  1555.                 } else {
  1556.                     etc_beep();
  1557.                     return(1);
  1558.                 }
  1559.             }
  1560.             /* 何か他 */
  1561. /*
  1562. etc_beep();etc_beep();etc_beep();
  1563. window0();printf("[%x]",c);binkey();
  1564. */
  1565.             if (wp == TAIL) {
  1566.                 if ((c == XF_NEXT_PAGE_KEY) || (c == FEP_HELP_CODE)) {    /* ROLL UP */
  1567.                     return(pn);
  1568.                 }
  1569.                 return(-1);
  1570.             } else {
  1571.                 return(pn+1);
  1572.             }
  1573.             }
  1574.         } else {    /* ^V だ */
  1575.             if (wp == TAIL) {
  1576.                 return(-1);
  1577.             } else {
  1578.                 return(pn+1);
  1579.             }
  1580.         }
  1581.     }
  1582. }
  1583.  
  1584. /* 表示する */
  1585. /* 上下にスクロールする */
  1586. /* wp と bp を更新する */
  1587. /* 終了フラグを返す */
  1588. int
  1589. prnt_do_1page_view_sub(UBYTE mode,UNIT **wpp,int *bp0,int pn,PM_UNIT page_mem[],int xr,int yr)
  1590. {
  1591.     int up,dn;    /* 表示している範囲 */
  1592.     int yc,yc0;        /* y カウンタ */
  1593.     UNIT *wp,*p;
  1594.     int bp;
  1595.     UBYTE w0[VERY_LONG_LINE];
  1596.     int yhaba = (((LYW_UPPER+LYW_MAIN+LYW_UNDER)*3/2)+PRN_V_PITCH)/yr;
  1597.     int yh,ygeta;
  1598.     int ii;
  1599.     UINT c;
  1600.     PM_UNIT line_mem[MAX_MEM_LINE];
  1601.  
  1602.     wp = *wpp;
  1603.     bp = *bp0;
  1604.     ii = 0;
  1605.  
  1606.     prnt_vp_init_line(line_mem);
  1607.  
  1608.     yc = 0;
  1609.  
  1610.     prnt_vp_store_line(line_mem,wp,bp,ii);    /* 記録 */
  1611.  
  1612.     /* 表示出来る分だけ表示する */
  1613.     while((ii < PAGE) && ((yc + yhaba) < 30*16) && (wp != TAIL)) {    /* もう1行処理できる */
  1614.         /* yc から1行処理 */
  1615.  
  1616.         prnt_vp_trace_line(&wp,&bp,w0);        /* w0 に1行分入る */
  1617.         ii++;
  1618.         prnt_vp_store_line(line_mem,wp,bp,ii);    /* 記録 */
  1619.  
  1620.         yh = prnt_bit_convrt_24(w0,0,LYW_UPPER,LYW_MAIN,LYW_UNDER,PRN_JIZUME);
  1621.         yc += prnt_send_1line_to_prn_view(yc,0,yh,xr,yr);
  1622.     }
  1623.     if ((ii >= PAGE) || (wp == TAIL)) {    /* 表示しきった */
  1624.         *wpp = wp;
  1625.         *bp0 = bp;
  1626.         return(0);
  1627.     }
  1628.  
  1629.     if (mode == 'V'-'@') {    /* 連続モード */
  1630.         return(0);
  1631.     }
  1632.     /* 表示しきってないのでスクロール作業が必要 */
  1633.     up = 0;        /* 最上行 */
  1634.     dn = ii-1;    /* 最下行 */
  1635.     ygeta = 0;
  1636.     yc0 = 0;    /* 上点 */
  1637. /*
  1638. window0();
  1639. printf("(%d)(%d)",up,dn);
  1640. getchar();
  1641. */
  1642.     ii = prnt_vp_get_line(line_mem,dn);
  1643.     p = line_mem[ii].LP;
  1644.  
  1645.     while(1) {
  1646.         UBYTE ww[MAXLINE];
  1647.  
  1648.     if (p == TAIL) {
  1649.         sprintf(ww," %d 頁目(最終)([F1]=最初, [F2]=最後, \\
  1650. [ROLL DOWN]=前頁, 数値+NL=その頁, [ESC]=中止)…",pn);
  1651.     } else {
  1652.         sprintf(ww," %d 頁目([F1]=最初, [F2]=最後, \\
  1653. [ROLL DOWN]=前頁, 数値+NL=その頁, [ESC]=中止)…",pn);
  1654.     }
  1655.  
  1656.         if (up) {        /* ↑ 可能 */
  1657.             strcat(ww,"↑");
  1658.         }
  1659.         if ((dn != (PAGE - 1)) && (wp != TAIL)) {    /* ↓ 可能 */
  1660.             strcat(ww,"↓");
  1661.         }
  1662.         strcat(ww,"でスクロール");
  1663.         under_print_view(ww);
  1664.         disp_cursor_on();
  1665.         fep_key_clear();
  1666. /*error("@");*/
  1667.         c = fep_inkey_raw0();
  1668. /*error("@@");*/
  1669.         disp_cursor_off();
  1670.         if ((c == XF_NEXT_BLOCK_KEY) && (dn != (PAGE - 1)) && (wp != TAIL)) {    /* 下向き矢印 */
  1671.             /* 1行スクロールアップ */
  1672.             int yoyuu;
  1673.  
  1674.             yoyuu = 30*16 - yc;    /* 下にこれだけ余裕がある */
  1675.             ygeta = prnt_view_scroll_up(yhaba-yoyuu);
  1676.                 /* yhaba を確保するためにはこれだけスクロールする必要がある */
  1677.             yc -= ygeta;    /* 結局下点はこれだけ上がった */
  1678.             yc0 -= ygeta;    /* 上点もこれだけ上がる */
  1679.             up++;
  1680.             dn++;        /* 1行すすむ */
  1681.             /* dn を表示 */
  1682.             ii = prnt_vp_get_line(line_mem,dn);
  1683.             wp = line_mem[ii].LP;
  1684.             bp = line_mem[ii].BP;
  1685.  
  1686.             if (wp == TAIL) {
  1687.                 continue;
  1688. /*                *wpp = wp;
  1689.                 *bp0 = bp;
  1690.                 return(0);*/
  1691.             }
  1692.             prnt_vp_trace_line(&wp,&bp,w0);        /* w0 に1行分入る */
  1693.             prnt_vp_store_line(line_mem,wp,bp,dn+1);    /* 記録 */
  1694.             yh = prnt_bit_convrt_24(w0,0,LYW_UPPER,LYW_MAIN,LYW_UNDER,PRN_JIZUME);
  1695.             prnt_send_1line_to_prn_view(yc,0,yh,xr,yr);
  1696.             yc += yhaba;    /* 表示したから下点は yhaba 下がる */
  1697.             yc0 += yhaba;    /* 1行たぐるからこうなる */
  1698.  
  1699. /*window0();printf("(%d)(%d)[%d]",yc,yc0,ygeta);*/
  1700. /*sprintf(ww,"(%d)(%d)[%d]",yc,yc0,ygeta);under_print0(ww);*/
  1701.         } else if ((c == XF_BEFORE_BLOCK_KEY) && up) {    /* 上向き矢印 */
  1702.             /* 1行スクロールダウン */
  1703.             int yoyuu;
  1704.  
  1705.             yoyuu = yc0;    /* 上にこれだけ余裕がある */
  1706.             ygeta = prnt_view_scroll_dn(yhaba-yoyuu);
  1707.                 /* yhaba を確保するためにはこれだけスクロールする必要がある */
  1708.             yc0 += ygeta;    /* 上点はこれだけ下がった */
  1709.             yc += ygeta;    /* 下点もこれだけ下がる */
  1710.             yc0 -= yhaba;    /* 表示すべき上点は yhaba 上 */
  1711.             yc -= yhaba;    /* 1行たぐるからこうなる */
  1712.             up--;
  1713.             dn--;
  1714.             /* up を表示 */
  1715.             ii = prnt_vp_get_line(line_mem,up);
  1716.             wp = line_mem[ii].LP;
  1717.             bp = line_mem[ii].BP;
  1718.  
  1719.             prnt_vp_trace_line(&wp,&bp,w0);        /* w0 に1行分入る */
  1720.             yh = prnt_bit_convrt_24(w0,0,LYW_UPPER,LYW_MAIN,LYW_UNDER,PRN_JIZUME);
  1721.             prnt_send_1line_to_prn_view(yc0,0,yh,xr,yr);
  1722. /*sprintf(ww,"(%d)(%d)",yc,yc0);under_print0(ww);*/
  1723.         } else if ((c == XF_NEXT_BLOCK_KEY) || (c == XF_BEFORE_BLOCK_KEY)) {
  1724.             continue;    /* 何もしない */
  1725.         } else {
  1726.             *wpp = wp;
  1727.             *bp0 = bp;
  1728. /*error("A");*/
  1729.             return(c);    /* END or NEXT PAGE */
  1730.         }
  1731.     }
  1732. }
  1733.  
  1734. /* バッファ上にイメージを展開する */
  1735. /* 新しいドット値を返す */
  1736. int
  1737. prnt_do_up_margin_view(int xr,int yr)
  1738. {
  1739.     register int i;
  1740.  
  1741.     init_clear_screen();
  1742.     return(PRN_UP_MARGIN/yr);
  1743. }
  1744.  
  1745. void
  1746. prnt_repo_view_num(STR p)
  1747. {
  1748.     UBYTE w[MAXLINE];
  1749.  
  1750.     sprintf(w,"頁数指定(終了=<NL>, 中止=[ESC])*%s",p);
  1751. /*
  1752. window0();
  1753. printf("[%s]",w);binkey();
  1754. */
  1755.     under_print_view(w);
  1756. }
  1757.  
  1758. /* p == TAIL なら、その旨表示 */
  1759. void
  1760. prnt_repo_view(int pn,UNIT *p)
  1761. {
  1762.     UBYTE w[MAXLINE*2];
  1763.  
  1764.     if (p == TAIL) {
  1765.         sprintf(w," %d 頁目(最終)([F1]=最初, [F2]=最後, \\
  1766. [ROLL DOWN]=前頁, 数値+NL=その頁, [ESC]=中止)…",pn);
  1767.     } else {
  1768.         sprintf(w," %d 頁目([F1]=最初, [F2]=最後, \\
  1769. [ROLL DOWN]=前頁, 数値+NL=その頁, [ESC]=中止)…",pn);
  1770.     }
  1771.     under_print_view(w);
  1772. }
  1773.  
  1774. /* 第n頁の先頭を求める */
  1775. /* インデックスを返す */
  1776. int
  1777. prnt_vp_get(PM_UNIT page_mem[],int n)
  1778. {
  1779.     register int i,w,max,maxi;
  1780.     int bp;
  1781.     UNIT *wp;
  1782.  
  1783.     for(i=0;i<MAX_MEM_PAGE;i++) {
  1784.         if (page_mem[i].PN == n) {    /* ヒット */
  1785.             return(i);
  1786.         }
  1787.     }
  1788.     /* 無い */
  1789.     /* 作って返す */
  1790.     maxi = prnt_vp_maxi(page_mem,n);
  1791.     max = page_mem[maxi].PN;
  1792.     wp = page_mem[maxi].LP;
  1793.     bp = page_mem[maxi].BP;
  1794.     i = maxi;
  1795.     for(;max < n;max++) {
  1796.         if (wp = prnt_vp_trace_page(wp,&bp)) {        /* 有効な頁である */
  1797.             i = prnt_vp_store(page_mem,wp,bp,max+1);    /* 保存する */
  1798. /*
  1799. window0();
  1800. printf("[%d]\n",bp);binkey();
  1801. */
  1802.         } else {    /* 終わりに達した */
  1803.                 /* 最後の頁を返す */
  1804.             break;
  1805.         }
  1806.     }
  1807.     /* 達した */
  1808.     return(i);
  1809. }
  1810.  
  1811.  
  1812. /*************************************************/
  1813.  
  1814. /* 行の先頭を格納する */
  1815. /* 格納したインデックスを返す */
  1816. int
  1817. prnt_vp_store_line(PM_UNIT line_mem[],UNIT *wp,int bp,int pn)
  1818. {
  1819.     register int i,w;
  1820.  
  1821.     for(i=0;i<MAX_MEM_LINE;i++) {
  1822.         if ((w = line_mem[i].PN) == pn) {    /* 既にある */
  1823.             return(i);            /* 何もせずに帰る */
  1824.         }
  1825.         if (w == -1) {    /* フリーだ */
  1826.             line_mem[i].LP = wp;
  1827.             line_mem[i].BP = bp;
  1828.             line_mem[i].PN = pn;
  1829.             return(i);
  1830.         }
  1831.     }
  1832.     /* フリーが無い */
  1833.     for(i=0;i<MAX_MEM_LINE;i++) {
  1834.         if (line_mem[i].PN != 0) {    /* 先頭頁ではない */
  1835.             line_mem[i].LP = wp;    /* 行をコロス */
  1836.             line_mem[i].BP = bp;
  1837.             line_mem[i].PN = pn;
  1838.             return(i);
  1839.         }
  1840.     }
  1841.     error("???3");
  1842. }
  1843.  
  1844. /* n 未満の最大を与えるインデックスを返す */
  1845. int
  1846. prnt_vp_maxi_line(PM_UNIT line_mem[],int n)
  1847. {
  1848.     register int i,w,max,maxi;
  1849.  
  1850.     max = line_mem[maxi = 0].PN;    /* 最初が初期値 */
  1851.     for(i=0;i < MAX_MEM_LINE;i++) {
  1852.         if (((w = line_mem[i].PN) < n) && (w > 0) && (max > w)) {
  1853.             max = w;
  1854.             maxi = i;
  1855.         }
  1856.     }
  1857.     return(maxi);
  1858. }
  1859.  
  1860. /* wp の bp から1行トレースし、rets に文字列を返す */
  1861. /* rets が NULL ならトレースし、次の行へのポインタを返すだけ */
  1862. /* 次の wp と、bp を返す */
  1863. /* TAIL に達したら wp に TAIL を返す */
  1864. void
  1865. prnt_vp_trace_line(UNIT **wp0,int *bp0,STR rets)
  1866. {
  1867.     UNIT *wp;
  1868.     int bp;
  1869.     UBYTE ws[VERY_LONG_LINE],w0[VERY_LONG_LINE];
  1870.     int i;
  1871.  
  1872.     wp = *wp0;
  1873.     bp = *bp0;
  1874.     if (PRN_JIZUME == CURRENT_JIZUME) {    /* これなら面倒はない */
  1875.         if (rets) {
  1876.             line_get_body(rets,wp);
  1877.         }
  1878.         wp = wp->ATO;
  1879.         *wp0 = wp;
  1880.         *bp0 = bp;
  1881.         return;
  1882.     }
  1883.  
  1884.     line_get_body(w0,wp);
  1885.     wp = wp->ATO;
  1886.     if (bp) {
  1887.         strcpy(w0,&w0[bp]);
  1888.     }
  1889.  
  1890.     cut_line(w0,ws,w0,PRN_JIZUME);
  1891.     if (!*w0) {    /* 1行取れなかった */
  1892.         while(1) {
  1893.             if (wp == TAIL) {
  1894.                 *w0 = EOS;
  1895.                 break;
  1896.             }
  1897.             /* 後がある */
  1898.             strcpy(w0,ws);    /* 戻す */
  1899.             line_cat_body(w0,wp);    /* 追加する */
  1900.             wp = wp->ATO;
  1901.             cut_line(w0,ws,w0,PRN_JIZUME);
  1902.             if (*w0) {    /* 1行取れた */
  1903.                 break;
  1904.             }
  1905.         }
  1906.     }
  1907.     if (*w0) {
  1908.         *bp0 = line_length(*wp0 = wp->MAE) - strlen(w0);
  1909.     } else  {
  1910.         *wp0 = wp;
  1911.         *bp0 = bp;
  1912.     }
  1913.     if (rets) {
  1914.         strcpy(rets,ws);
  1915.     }
  1916.     return;
  1917. }
  1918.  
  1919. void
  1920. prnt_vp_init_line(PM_UNIT line_mem[])
  1921. {
  1922.     register int pmc;
  1923.  
  1924.     for(pmc = 0;pmc < MAX_MEM_LINE;pmc++) {
  1925.         line_mem[pmc].PN = -1;    /* ページインデックスの初期化 */
  1926.     }
  1927.     page_last.PN = -1;
  1928. }
  1929.  
  1930.  
  1931. /* 第n行の先頭を求める */
  1932. /* インデックスを返す */
  1933. int
  1934. prnt_vp_get_line(PM_UNIT line_mem[],int n)
  1935. {
  1936.     register int i,w,max,maxi;
  1937.     int bp;
  1938.     UNIT *wp;
  1939.  
  1940.     for(i=0;i<MAX_MEM_LINE;i++) {
  1941.         if (line_mem[i].PN == n) {    /* ヒット */
  1942.             return(i);
  1943.         }
  1944.     }
  1945.     /* 無い */
  1946.     /* 作って返す */
  1947.     maxi = prnt_vp_maxi_line(line_mem,n);
  1948.     max = line_mem[maxi].PN;
  1949.     wp = line_mem[maxi].LP;
  1950.     bp = line_mem[maxi].BP;
  1951.     i = maxi;
  1952.     for(;max < n;max++) {
  1953.         prnt_vp_trace_line(&wp,&bp,NULL);
  1954.         if (wp == TAIL) {
  1955.             break;
  1956.         } else {
  1957.             i = prnt_vp_store_line(line_mem,wp,bp,max+1);    /* 保存する */
  1958.         }
  1959.     }
  1960.     /* 達した */
  1961.     return(i);
  1962. }
  1963.  
  1964. /* yhaba を越えるだけの4ラスタブロックをスクロールアップする */
  1965. /* 実際にスクロールしたラスタ数を返す */
  1966. int
  1967. prnt_view_scroll_up(int yhaba)
  1968. {
  1969.     register int i,ii;
  1970.  
  1971.     i = yhaba>>2;
  1972.     if (yhaba & 3) {
  1973.         i++;
  1974.     }
  1975.     for(ii=0;ii<i;ii++) {
  1976.         TXRASCPY(1*256+0,(30*16/4)-1,3);
  1977.     }
  1978.     i *= 4;
  1979.     etc_era_box(0,30*16-i,95,i);
  1980.     return(i);
  1981. }
  1982.  
  1983. /* yhaba を越えるだけの4ラスタブロックをスクロールダウンする */
  1984. /* 実際にスクロールしたラスタ数を返す */
  1985. int
  1986. prnt_view_scroll_dn(int yhaba)
  1987. {
  1988.     register int i,ii;
  1989.  
  1990.     i = yhaba>>2;
  1991.     if (yhaba & 3) {
  1992.         i++;
  1993.     }
  1994.     for(ii=0;ii<i;ii++) {
  1995.         TXRASCPY(((30*16/4)-1)*256+(30*16/4),(30*16/4)-0,3 | 0x8000);
  1996.     }
  1997.     i *= 4;
  1998.     etc_era_box(0,0,95,i);
  1999.     return(i);
  2000. }
  2001.  
  2002. /* プリンタパラメータのダイレクト数値入力 */
  2003. void
  2004. prnt_direct_number(int xp,UBYTE c)
  2005. {
  2006.     int n;
  2007.  
  2008.     n = c - '0';
  2009.  
  2010.     while(1) {
  2011.         switch(xp) {
  2012.         case 0:
  2013. /*        PRN_TATE_MODE = !PRN_TATE_MODE;*/
  2014.         etc_beep();
  2015.         return;
  2016.         break;
  2017.  
  2018.         case 1:
  2019.         PRN_JIZUME = n;
  2020.         break;
  2021.  
  2022.         case 2:
  2023.         PAGE = n;
  2024.         break;
  2025.  
  2026.         case 3:
  2027.         PRN_UP_MARGIN = n;
  2028.         break;
  2029.  
  2030.         case 4:
  2031.         PRN_LEFT_MARGIN = n;
  2032.         break;
  2033.  
  2034.         case 5:
  2035.         PRN_H_PITCH = n;
  2036.         break;
  2037.  
  2038.         case 6:
  2039.         if ((c == '0') && (n > 50)) {
  2040.             n = 0;
  2041.         }
  2042.         PRN_V_PITCH = min(n,50);
  2043.         break;
  2044.  
  2045.         default:
  2046.         etc_beep();
  2047.         return;
  2048.         break;
  2049.         }
  2050.         prnt_do_disp(xp);
  2051.         fep_key_clear();
  2052.  
  2053.         c = toupper(fep_inkey_raw0());
  2054.         if (('0' <=c) && (c <= '9')) {    /* 数字入力 */
  2055.             n = (n*10 + (c-'0')) % 1000;
  2056.         } else {
  2057.             fep_push_key(c);
  2058.             return;
  2059.         }
  2060.     }
  2061. }
  2062.  
  2063. void
  2064. prnt_direct_number2(int xp,UBYTE c)
  2065. {
  2066.     int n;
  2067.  
  2068.     n = c - '0';
  2069.  
  2070.     while(1) {
  2071.         switch(xp) {
  2072.         case 0:
  2073.         prnt_top = n;
  2074.         break;
  2075.  
  2076.         case 1:
  2077.         prnt_last = n;
  2078.         break;
  2079.  
  2080.         case 2:
  2081.         etc_beep();
  2082.         return;
  2083. /*        prnt_pitch = !prnt_pitch;*/
  2084.         break;
  2085.  
  2086.         default:
  2087.         etc_beep();
  2088.         return;
  2089.         break;
  2090.         }
  2091.         prnt_do_disp_2(xp);
  2092.         fep_key_clear();
  2093.  
  2094.         c = toupper(fep_inkey_raw0());
  2095.         if (('0' <=c) && (c <= '9')) {    /* 数字入力 */
  2096.             n = (n*10 + (c-'0')) % 1000;
  2097.         } else {
  2098.             fep_push_key(c);
  2099.             return;
  2100.         }
  2101.     }
  2102. }
  2103.  
  2104.